package com.codelab.statemachine.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.codelab.statemachine.mybatis.dataobject.TaskDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.annotation.OnStateEntry;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.codelab.statemachine.task.TaskStateMachineBuilder.MACHINEID;

@WithStateMachine(id=MACHINEID)
@Slf4j
public class TaskEventConfig {

    @Autowired
    private CommonTaskService taskService;

    @OnStateEntry(target = "CREATE")
    public void create(){

        log.info("---创建任务---");
    }

    @OnStateEntry(target = "READY")
    public void prepare(StateContext<TaskStates, TaskEvents> stateContext) {

        String taskid = (String) stateContext.getExtendedState().getVariables().get("taskid");
        log.info("---任务[{}]---状态：READY！---",taskid);
        taskService.updateStatus(taskid,TaskStates.READY.toString());
    }

    @OnStateEntry(target = "RUNNING")
    public void execute(StateContext<TaskStates, TaskEvents> stateContext){
        String taskid = (String) stateContext.getExtendedState().getVariables().get("taskid");
        taskService.updateStatus(taskid,TaskStates.RUNNING.toString());
        log.info("---任务[{}]---状态：RUNNING！---",taskid);
    }

    @OnStateEntry(target = "SUCCESS")
    public void done(StateContext<TaskStates, TaskEvents> stateContext){
        String taskid = (String) stateContext.getExtendedState().getVariables().get("taskid");
        taskService.updateStatus(taskid,TaskStates.SUCCESS.toString());
        taskService.updateProcess(taskid, 1);
        log.info("---任务[{}]---状态：SUCCESS！---",taskid);
    }

    @OnStateEntry(target = "FAIL")
    public void error(StateContext<TaskStates, TaskEvents> stateContext) {
        String taskid = (String) stateContext.getExtendedState().getVariables().get("taskid");
        String msg = (String) stateContext.getExtendedState().getVariables().get("msg");
        if(StrUtil.isNotBlank(msg)){
            taskService.updateMessage(taskid, msg);
        }

        //taskService.updateStatus(taskid,TaskStates.FAIL.toString());

        List<TaskDO> allTasks = taskService.getAllTaskById(taskid);
        TaskDO root = allTasks.get(0);

        if(StrUtil.isNotBlank(msg)){
            StringBuilder sb = new StringBuilder(root.getMessage()).append(msg);
            taskService.updateMessage(root.getId(), sb.toString());
            //taskService.updateStatus(root.getId(),TaskStates.FAIL.toString());
        }

        taskService.update(new UpdateWrapper<TaskDO>().lambda()
                .set(TaskDO::getStatus,TaskStates.FAIL.toString())
                .set(TaskDO::getUpdateTime, LocalDateTime.now())
                .in(TaskDO::getId, allTasks.stream().map(TaskDO::getId).collect(Collectors.toList())));

        log.info("---任务[{}]---状态：FAIL！---",taskid);
    }
}
